#include "Mydict.h"
#include <fstream>
#include <sstream>

Mydict* Mydict::createInstance()
{
    if(nullptr==_pInstance){
        _pInstance=new Mydict();
    }
    return _pInstance;
}

void Mydict::destroy()
{
    if(nullptr!=_pInstance){
        delete _pInstance;
        _pInstance=nullptr;
    }
}

void Mydict::init(const char* dictEnPath,const char* dictCnPath)
{
    read(dictEnPath);
    read(dictCnPath);
    build_index();
}

void Mydict::read(const char*filepath)
{
    ifstream ifs(filepath);
    if(!ifs){
        perror("ifstream_en");
        return;
    }
    
    string line;
    while(getline(ifs,line)){
        istringstream iss(line);
        string word;
        int freq;
        iss>>word>>freq;
        _dict.push_back(make_pair(word,freq));
    }
    ifs.close();
}

void Mydict::build_index()
{
    for(size_t idx=0;idx!=_dict.size();idx++)
    {
        char mark=_dict[idx].first[0];
        if(mark & 0x80)//是汉字
        {
            deal_cn(_dict[idx].first,idx);
        }
        else if((mark>='a'&&mark<='z')||(mark>='A'&&mark<='Z')||
                (mark>='0'&&mark<='9'))//英文或数字
        {
            deal_en(_dict[idx].first,idx);
        }
    }
}
void Mydict::deal_cn(const string& word,int cnt)
{
    //只取首个字符
    if(word==string()) return;
    set<int> s({cnt});

    string key;
    size_t idx=0;
    int len=getUtf8CharLength(word[idx]);
    while(len--){
        key+=word[idx++];
    }
    auto it=_index_table.insert(make_pair(key,s));
    if(!it.second){
        _index_table[key].insert(cnt);
    }
    
}
void Mydict::deal_en(const string& word,int cnt)
{
    //只取首个字符
    if(word==string()) return;
    set<int> s({cnt});
    string key;
    key+=word[0];
    auto it=_index_table.insert(make_pair(key,s));
    if(!it.second){
        _index_table[key].insert(cnt);
    }
}

int Mydict::getUtf8CharLength(char c)
{
    int len=0;
    if(c>0) return len+1;
    while(c<0){
        len++;
        c=c<<1;
    }
    return len;
}

void Mydict::store_index(const char* filepath)
{
    ofstream oss(filepath);
    if(!oss){
        perror("ofstream");
        return;
    }
    for(auto &elem:_index_table)
    {
        oss<<elem.first<<" ";
        for(auto &cnt:elem.second){
            oss<<cnt<<" ";
        }
        oss<<endl;
    }
    oss.close();
}
vector<pair<string,int>>& Mydict::getDict()
{
    return _dict;
}

unordered_map<string,set<int>>& Mydict::getIndexTable()
{
    return _index_table;
}

Mydict* Mydict::_pInstance=nullptr;
